﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace Asol.Reporting.Support
{
    /// <summary>
    /// Třída nabízející podporu po práci s XML soubory (načtení, ukládání, tvorba elementů a atributů)
    /// </summary>
    public class XmlDoc : XmlDocument
    {
        /// <summary>
        /// Konstruktor
        /// </summary>
        public XmlDoc() { }
        /// <summary>
        /// Konstruktor, který vytvoří root element daného jména
        /// </summary>
        /// <param name="rootElementName"></param>
        public XmlDoc(string rootElementName)
            : base()
        {
            XmlElement rootElement = this.CreateElement(rootElementName);
            this.AppendChild(rootElement);
            this.RootElement = rootElement;
        }
        /// <summary>
        /// Přidá schema dokumentu
        /// </summary>
        /// <param name="targetNamespace"></param>
        /// <param name="id"></param>
        public void AddSchema(string targetNamespace, string id)
        {
            System.Xml.Schema.XmlSchema ts = new System.Xml.Schema.XmlSchema();
            ts.TargetNamespace = targetNamespace;
            ts.Id = id;
            this.Schemas.Add(ts);
        }
        /// <summary>
        /// Root element. Lze jej vytvořit v konstruktoru.
        /// </summary>
        public XmlElement RootElement { get; private set; }
        /// <summary>
        /// Vytvoří XML element daného jména, vloží jej do Childs daného elementu a vrátí jej.
        /// </summary>
        /// <param name="parentElement"></param>
        /// <param name="elementName"></param>
        /// <returns></returns>
        public XmlElement CreateElementIn(XmlElement parentElement, string elementName)
        {
            string name = CreateXmlName(elementName);
			XmlElement xElement = this.CreateElement(name);
            parentElement.AppendChild(xElement);
			return xElement;
        }
        /// <summary>
        /// Vytvoří XML atribut daného jména a hodnoty, vloží jej do daného elementu a vrátí jej.
        /// </summary>
        /// <param name="xElement"></param>
        /// <param name="attName"></param>
        /// <param name="attValue"></param>
        /// <returns></returns>
        public XmlAttribute AddAttributeTo(XmlElement xElement, string attName, string attValue)
        {
            XmlAttribute xAttribute = this.CreateAttribute(attName);
            if (attValue != null)
                xAttribute.Value = attValue;
            xElement.Attributes.Append(xAttribute);
            return xAttribute;
        }
        /// <summary>
        /// Z daného textu vyloučí nevhodné znaky a výsledek vrátí. Nemění ToLower.
        /// Odstraňuje ampersand, čárku, mezeru, hranaté závorky.
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public static string CreateXmlName(string name)
        {
            string excludeChars = "`, []";
            string xmlName = name;
            foreach (char c in excludeChars)
            {
                if (xmlName.Contains(c))
                    xmlName = xmlName.Replace(c.ToString(), "");
            }
            return xmlName;
        }
        /// <summary>
        /// Vytvoří nový objekt a načte do něj obsah daného souboru
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static XmlDoc CreateFromFile(string fileName)
        {
            XmlDoc xmlDoc = new XmlDoc();
            xmlDoc.Load(fileName);
            xmlDoc.RootElement = xmlDoc.DocumentElement;
            return xmlDoc;
        }
        /// <summary>
        /// Uloží se do daného souboru
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="format"></param>
        public void Save(string fileName, bool format)
        {
            XmlWriterSettings sett = new XmlWriterSettings();
            sett.ConformanceLevel = ConformanceLevel.Document;
            sett.Encoding = Encoding.UTF8;
            sett.Indent = true;
            sett.IndentChars = "  ";
            sett.NamespaceHandling = NamespaceHandling.OmitDuplicates;
            sett.NewLineHandling = NewLineHandling.Entitize;
            sett.NewLineChars = Environment.NewLine;
            sett.NewLineOnAttributes = false;
            sett.OmitXmlDeclaration = false;

            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(fileName, false, Encoding.UTF8))
            {
                XmlWriter xw = XmlWriter.Create(sw, sett);
                this.WriteTo(xw);
                xw.Flush();
            }
        }
    }
}
